﻿Public Class ClassPrez
    'Présentation visio
    'Utilisée pour conserver la présentation de chaque document ouvert 
    'L'objet sera séralisé en XML et enregistré comme données de solution à même le fichier Visio
    Public DocID As Integer
    Public Titre As String
    Public ModelePP As String
    Public PresentationPP As String
    'Il ne semble pas possible de serialiser un arraylist. On transfert donc en collection... ?
    Public Diapos As System.Collections.ArrayList
    Public Index As Integer

    Public Sub New()
        Me.DocID = 0
        Me.Titre = ""
        Me.ModelePP = ""
        Me.Diapos = New System.Collections.ArrayList
        Me.Index = -1
    End Sub

    Public Sub Clear()
        Me.DocID = ""
        Me.Diapos.Clear()
        Me.Index = -1
    End Sub

    Public Function NewDiapoID() As Integer
        'Etape 1 : Construire une collection des ID déjà pris
        Dim colID As New Collection
        For Each oDiapo As ClassDiapo In Me.Diapos
            colID.Add(oDiapo.ID, oDiapo.ID)
        Next
        'Etape 2 : Trouver le premier id Libre
        Dim iNo As Integer = 1
        Do While colID.Contains(iNo)
            iNo += 1
        Loop
        Return iNo
    End Function

    Public Property XML() As String
        Set(value As String)
            Dim oXmlDoc As New System.Xml.XmlDocument
            oXmlDoc.LoadXml(value)
            Dim oRoot As System.Xml.XmlElement = oXmlDoc.DocumentElement
            'MsgBox("SET XML:" & oRoot.InnerXml)
            'On va faire l'extraction ici   
            Me.Titre = GetPropXML(oRoot, "Titre")
            Me.ModelePP = GetPropXML(oRoot, "ModelePP")
            Me.PresentationPP = GetPropXML(oRoot, "PresentationPP")
            Me.Diapos.Clear()
            For Each oDiapoXML As System.Xml.XmlElement In oRoot.GetElementsByTagName("Diapo")
                Dim oDiapo As New ClassDiapo(0)
                oDiapo.FromXMLElement(oDiapoXML)
                Me.Diapos.Add(oDiapo)
            Next
        End Set
        Get
            'Document XML avec son élément racine dans le format SolutionXML accepté par Visio
            Dim oXmlDoc As New System.Xml.XmlDocument
            Dim oRoot As System.Xml.XmlElement = oXmlDoc.CreateElement("SolutionXML")
            oXmlDoc.AppendChild(oRoot)
            Dim oName As System.Xml.XmlAttribute = oXmlDoc.CreateAttribute("Name")
            oName.Value = "VisioPrez"
            oRoot.Attributes.Append(oName)
            Dim oNameSpace As System.Xml.XmlAttribute = oXmlDoc.CreateAttribute("xmlns:MyNamespace")
            oNameSpace.Value = "http://MySchemaUrl..."
            oRoot.Attributes.Append(oNameSpace)
            'Contenu propre à la solution - les diapos
            AjoutePropXML(oXmlDoc, oRoot, "Titre", Me.Titre)
            AjoutePropXML(oXmlDoc, oRoot, "ModelePP", Me.ModelePP)
            AjoutePropXML(oXmlDoc, oRoot, "PresentationPP", Me.PresentationPP)
            For Each oDiapo As ClassDiapo In Me.Diapos
                oRoot.AppendChild(oDiapo.ToXMLElement(oXmlDoc))
            Next
            'MsgBox("GET XML:" & oXmlDoc.InnerXml)
            Return oXmlDoc.InnerXml
        End Get
    End Property

    Public Sub NouvelleDiapo()
        If Not oApp.ActiveWindow Is Nothing Then
            'Pour l'instant on ajoute à la fin
            Dim oDiapo As New ClassDiapo(Me.NewDiapoID)
            oDiapo.Capturer()
            Me.Diapos.Insert(Me.Index + 1, oDiapo)
            'Me.Diapos.Add(oDiapo)
            Me.Index = Me.Index + 1
            Call Me.UpdateRibbon()
        End If
    End Sub

    Public Sub ReprendreDiapo()
        If Not oApp.ActiveWindow Is Nothing And Me.Index <> -1 Then
            CType(Me.Diapos(Me.Index), ClassDiapo).Capturer()
        End If
    End Sub

    Public Sub SupprimerDiapo()
        If Me.Index <> -1 Then
            Me.Diapos.RemoveAt(Me.Index)
            If Me.Index > Me.Diapos.Count - 1 Then Me.Index = Me.Diapos.Count - 1
        End If
        Me.Appliquer()
    End Sub

    Public Sub AllerDebut()
        If Me.Diapos.Count > 0 Then
            'AutoUpdate de la courante
            ReprendreDiapo()
            Me.Index = 0
            Me.Appliquer()
        Else
            Me.Index = -1
        End If
    End Sub

    Public Sub AllerFin()
        If Me.Diapos.Count > 0 Then
            'AutoUpdate de la courante
            ReprendreDiapo()
            Me.Index = Me.Diapos.Count - 1
            Me.Appliquer()
        End If
    End Sub

    Public Sub AllerPrecedente()
        If Me.Index > 0 Then
            'AutoUpdate de la courante
            ReprendreDiapo()
            Me.Index -= 1
            Me.Appliquer()
        End If
    End Sub

    Public Sub AllerSuivante()
        If (Me.Diapos.Count > 0) And (Me.Index < (Me.Diapos.Count - 1)) Then
            'AutoUpdate de la courante
            ReprendreDiapo()
            Me.Index += 1
            Me.Appliquer()
        End If
    End Sub

    Private Sub Appliquer()
        If Me.Index <> -1 Then CType(Me.Diapos(Me.Index), ClassDiapo).Appliquer()
        Call Me.UpdateRibbon()
    End Sub

    Public Sub Edit()
        If Me.Diapos.Count > 0 Then
            'Recapturer la diapo courante
            Me.ReprendreDiapo()
            'Copier les diapos dans le dialogue
            oFormPrez.Clear()
            oFormPrez.TextBoxTitre.Text = Me.Titre
            Dim iIndex As Integer = -1
            For Each oDiapo As ClassDiapo In Me.Diapos
                If oDiapo.GetThumbnail Is Nothing Then
                    oDiapo.Appliquer()
                    oDiapo.UpdateImages()
                End If
                oFormPrez.ImageList2.Images.Add(oDiapo.ID.ToString, oDiapo.GetThumbnail())
                Dim oItem As Windows.Forms.ListViewItem = oFormPrez.ListView1.Items.Add(oDiapo.ID.ToString, oDiapo.Titre, oDiapo.ID.ToString)
                oItem.Tag = oDiapo
                iIndex += 1
                If iIndex = Me.Index Then
                    oItem.Selected = True
                    oItem.EnsureVisible()
                End If
            Next
            'Afficher la fenêtre
            oFormPrez.ShowDialog()
            'Récupérer les infos    
            Me.Titre = oFormPrez.TextBoxTitre.Text
            Me.Diapos.Clear()
            For Each oItem As Windows.Forms.ListViewItem In oFormPrez.ListView1.Items
                Dim oDiapo As ClassDiapo = oItem.Tag
                oDiapo.Titre = oItem.Text
                Me.Diapos.Add(oDiapo)
            Next
            'Mettre à jour la diapo courante
            If oFormPrez.ListView1.SelectedIndices.Count > 0 Then Me.Index = oFormPrez.ListView1.SelectedIndices(0)
            If Me.Diapos.Count = 0 Then Me.Index = -1
            Me.UpdateRibbon()
        Else
            MsgBox("This document contains no VisioPrez Slide.")
        End If
    End Sub

    Public Sub ExporterPP(ByVal Modele As String, ByVal DataType As Microsoft.Office.Interop.PowerPoint.PpPasteDataType)
        'Méthode basée sur la sélection des éléments visibles avec enregistrer sous
        'La méthode Export s'applique aux objets Shape, Page et Selection...
        Try
            Dim oPP As New Microsoft.Office.Interop.PowerPoint.Application
            Windows.Forms.Application.DoEvents()
            oPP.Visible = True
            oPP.WindowState = Microsoft.Office.Interop.PowerPoint.PpWindowState.ppWindowNormal
            Dim oPresentation As Microsoft.Office.Interop.PowerPoint.Presentation
            If My.Computer.FileSystem.FileExists(Modele) Then
                oPresentation = oPP.Presentations.Open(Modele, Microsoft.Office.Core.MsoTriState.msoFalse, True, True)
            Else
                oPresentation = oPP.Presentations.Add(Microsoft.Office.Core.MsoTriState.msoCTrue)
            End If
            Dim iNoSlide As Integer = 1
            'Page titre
            Dim oSlideTitre As Microsoft.Office.Interop.PowerPoint.Slide = oPresentation.Slides.Add(iNoSlide, Microsoft.Office.Interop.PowerPoint.PpSlideLayout.ppLayoutCustom)
            oSlideTitre.Shapes.Title.TextFrame.TextRange.Text = Me.Titre
            'Diapos
            Dim sNomFic As String = My.Computer.FileSystem.GetTempFileName() & ".png"
            For Each oDiapo As ClassDiapo In Me.Diapos
                'Titre
                iNoSlide += 1
                Dim oSlide As Microsoft.Office.Interop.PowerPoint.Slide = oPresentation.Slides.Add(iNoSlide, Microsoft.Office.Interop.PowerPoint.PpSlideLayout.ppLayoutObject)
                oSlide.Select()
                oSlide.Shapes(1).TextFrame.TextRange.Text = oDiapo.Titre
                'Image
                oDiapo.Appliquer()
                Dim oSelection As Microsoft.Office.Interop.Visio.Selection = oApp.ActivePage.CreateSelection(Visio.VisSelectionTypes.visSelTypeEmpty)
                For Each oShape As Microsoft.Office.Interop.Visio.Shape In oApp.ActivePage.Shapes
                    'CONDITION BASÉ SUR LE BOUNDING RECT
                    Dim dLeft, dBottom, dRight, dTop As Double
                    oShape.BoundingBox(1, dLeft, dBottom, dRight, dTop)
                    Dim sName As String = oShape.Name
                    'Attention : viewrect marche avec les coordonnées de bas en haut...
                    If (dLeft >= oDiapo.vLeft) And (dRight <= oDiapo.vLeft + oDiapo.vWidth) And (dBottom <= oDiapo.vTop) And (dTop > oDiapo.vTop - oDiapo.vHeight) Then oSelection.Select(oShape, 2)
                Next
                If oSelection.Count > 0 Then
                    oSelection.Copy()
                    Dim oRange As Microsoft.Office.Interop.PowerPoint.ShapeRange = oSlide.Shapes.PasteSpecial(DataType)
                    'Temporaire
                    'oRange.Align(Microsoft.Office.Core.MsoAlignCmd.msoAlignCenters, True)
                    'oRange.Align(Microsoft.Office.Core.MsoAlignCmd.msoAlignMiddles, True)
                    Dim Ratio As Double = oSlide.Shapes(2).Width / oSlide.Shapes(2).Height
                    For Each oShape As Microsoft.Office.Interop.PowerPoint.Shape In oRange
                        oShape.Left = oSlide.Shapes(2).Left
                        oShape.Top = oSlide.Shapes(2).Top
                        Dim DeltaX As Double = oSlide.Shapes(2).Width - oShape.Width
                        Dim DeltaY As Double = oSlide.Shapes(2).Height - oShape.Height
                        Dim Delta As Double = 0
                        If DeltaX / Ratio < DeltaY Then
                            oShape.Width += DeltaX
                        Else
                            oShape.Height += DeltaY
                        End If
                        'If oShape.Width > oSlide.Shapes(2).Width Then oShape.Width = oSlide.Shapes(2).Width
                        'If oShape.Height > oSlide.Shapes(2).Height Then oShape.Height = oSlide.Shapes(2).Height
                    Next
                    oSlide.Shapes.Item(2).Delete()
                End If
            Next
            If My.Computer.FileSystem.FileExists(sNomFic) Then My.Computer.FileSystem.DeleteFile(sNomFic)
            oPP.Activate()
            oPP = Nothing
        Catch Ex As Exception
            MsgBox("Exportation error : " & Ex.Message)
        End Try
    End Sub

    Public Sub ExporterPP_Capture(ByVal Modele As String)
        'Méthode basée sur la capture écran de la fenêtre active de Visio
        'Difficulté : Pas encore trouvé de méthode pour identifier la zone de travail seulement, sans le contour de fenêtre, menus etc.
        Try
            'Phase 1 - Actualiser les images
            For Each oDiapo As ClassDiapo In Me.Diapos
                oDiapo.Appliquer()
                oDiapo.UpdateImages()
            Next
            Dim oPP As New Microsoft.Office.Interop.PowerPoint.Application
            Windows.Forms.Application.DoEvents()
            oPP.Visible = True
            oPP.WindowState = Microsoft.Office.Interop.PowerPoint.PpWindowState.ppWindowNormal
            Dim oPresentation As Microsoft.Office.Interop.PowerPoint.Presentation
            If My.Computer.FileSystem.FileExists(Modele) Then
                oPresentation = oPP.Presentations.Open(Modele, Microsoft.Office.Core.MsoTriState.msoFalse, True, True)
            Else
                oPresentation = oPP.Presentations.Add(Microsoft.Office.Core.MsoTriState.msoCTrue)
            End If
            Dim iNoSlide As Integer = 1
            'Page titre
            Dim oSlideTitre As Microsoft.Office.Interop.PowerPoint.Slide = oPresentation.Slides.Add(iNoSlide, Microsoft.Office.Interop.PowerPoint.PpSlideLayout.ppLayoutTitleOnly)
            If Me.Titre <> "" Then
                oSlideTitre.Shapes.Title.TextFrame.TextRange.Text = Me.Titre
            Else
                oSlideTitre.Shapes.Title.TextFrame.TextRange.Text = oApp.ActiveDocument.Name
            End If
            'Diapos
            Dim sNomFic As String = My.Computer.FileSystem.GetTempFileName() & ".png"
            For Each oDiapo As ClassDiapo In Me.Diapos
                'Methode backup - on prend l'image snapshot.
                oDiapo.GetImage.Save(sNomFic)
                iNoSlide += 1
                Dim oSlide As Microsoft.Office.Interop.PowerPoint.Slide = oPresentation.Slides.Add(iNoSlide, Microsoft.Office.Interop.PowerPoint.PpSlideLayout.ppLayoutObject)
                oSlide.Shapes(1).TextFrame.TextRange.Text = oDiapo.Titre
                Dim iLeft, iTop, iWidth, iHeight As Single
                iLeft = oSlide.Shapes.Item(2).Left
                iTop = oSlide.Shapes.Item(2).Top
                iWidth = oSlide.Shapes.Item(2).Width
                iHeight = oSlide.Shapes.Item(2).Height
                oSlide.Shapes.Item(2).Delete()
                oSlide.Shapes.AddPicture(sNomFic, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue, iLeft, iTop, iWidth, iHeight)
            Next
            My.Computer.FileSystem.DeleteFile(sNomFic)
            oPP.Activate()
            oPP = Nothing
        Catch Ex As Exception
            MsgBox("Exportation error : " & Ex.Message)
        End Try
    End Sub

    Public Sub UpdateRibbon()
        Globals.Ribbons.RibbonPrez.LabelDiapo.Label = Me.Index + 1 & "/" & Me.Diapos.Count
        If Me.Index = -1 Then
            Globals.Ribbons.RibbonPrez.LabelTitre.Label = "None"
        Else
            Globals.Ribbons.RibbonPrez.LabelTitre.Label = Me.Diapos(Me.Index).Titre
        End If

        Dim bDiapos As Boolean = (Me.Diapos.Count > 0)
        Globals.Ribbons.RibbonPrez.ButtonDebut.Enabled = bDiapos
        Globals.Ribbons.RibbonPrez.ButtonFin.Enabled = bDiapos
        Globals.Ribbons.RibbonPrez.ButtonSuiv.Enabled = bDiapos
        Globals.Ribbons.RibbonPrez.ButtonPrec.Enabled = bDiapos
        Globals.Ribbons.RibbonPrez.ButtonExport.Enabled = bDiapos
        Globals.Ribbons.RibbonPrez.ButtonSupprimer.Enabled = bDiapos
        Globals.Ribbons.RibbonPrez.Button1.Enabled = bDiapos
        Globals.Ribbons.RibbonPrez.Button2.Enabled = bDiapos
    End Sub
End Class
